import json
import re
import xml.etree.ElementTree as ET
from xml.dom import minidom
from datetime import datetime

with open("data.js", "r", encoding="utf-8") as f:
    content = f.read()

# 使用正则提取 JSON 内容（去除 var cdata = 前缀和结尾分号）
match = re.search(r'var\s+cdata\s*=\s*(\{.*\});?', content, re.DOTALL)
if not match:
    raise ValueError("未能匹配到 cdata 对象")

json_str = match.group(1)

# 将字符串解析成 Python 字典
json_data = json.loads(json_str)

contest = json_data['contest']  # 比赛信息
problem = json_data['problem']  # 题目信息，索引为0开始
teams = json_data['team']  # 队伍信息
frozen_minute = contest['frozen_minute']  # 封榜时间
solution = json_data['solution']

def dict_to_element(tag, d):
    elem = ET.Element(tag)
    for key, value in d.items():
        child = ET.SubElement(elem, key)
        child.text = str(value)
    return elem


def generate_xml(data):
    contest = ET.Element("contest")

    for key in ["info", "finalized"]:
        if key in data:
            contest.append(dict_to_element(key, data[key]))

    for key in ["region", "judgement", "language", "problem", "team", "run"]:
        for item in data.get(key, []):
            contest.append(dict_to_element(key, item))

    # 美化 XML（不带 XML 声明头）
    rough_string = ET.tostring(contest, encoding="utf-8")
    reparsed = minidom.parseString(rough_string)
    pretty = reparsed.toprettyxml(indent="    ")

    # 去掉 <?xml version="1.0" ?>
    return '\n'.join(pretty.split('\n')[1:])


fmt = "%Y-%m-%d %H:%M:%S"


def get_duration(start_time: str, end_time: str) -> str:
    start_dt = datetime.strptime(start_time, fmt)
    end_dt = datetime.strptime(end_time, fmt)

    delta = end_dt - start_dt
    total_seconds = int(delta.total_seconds())

    hours = total_seconds // 3600
    minutes = (total_seconds % 3600) // 60
    seconds = total_seconds % 60

    return f"{hours}:{minutes:02}:{seconds:02}"


def format_duration_from_minutes(total_minutes):
    total_seconds = int(total_minutes * 60)
    hours = total_seconds // 3600
    minutes = (total_seconds % 3600) // 60
    seconds = total_seconds % 60
    return f"{hours}:{minutes:02}:{seconds:02}"


region = []
team = []


def init_team_data(teams):
    idx = 1
    school = []
    for obj in teams:
        if school.count(obj['school']):
            continue
        region_obj = {
            "external-id": idx,
            "name": obj['school']
        }
        school.append(obj['school'])
        region.append(region_obj)
        idx += 1
    for obj in region:
        for t in teams:
            if obj['name'] == t['school']:
                team_obj = {
                    "id": t['team_id'][4:],
                    "external-id": obj['external-id'],
                    "region": obj['name'],
                    "name": t['name'],
                    "university": obj['name'],
                    "university-short-name": obj['name']
                }
                team.append(team_obj)
                print(team_obj)


xml_problem = []
problem_map = {}


def init_problem(problem):
    ch = 'A'
    for obj in problem:
        pobj = {
            "id": obj['num'] + 1,
            "letter": ch,
            "name": ch
        }
        problem_map[obj['problem_id']] = pobj['id']
        ch = chr(ord(ch) + 1)
        xml_problem.append(pobj)


run = []


def init_solution(sol):
    for obj in sol:
        solved = "",
        penalty = "",
        result = "",
        if obj['result'] == 4:
            solved = "true"
            penalty = "false"
            result = "AC"
        elif obj['result'] == 11:
            solved = "false"
            penalty = "false"
            result = "CE"
        else:
            solved = "false"
            penalty = "true"
            result = "WA"
        run_data = {
            "id": obj['solution_id'],
            "judged": "True",
            "language": "C++",
            "problem": problem_map[obj['problem_id']],
            "team": obj['user_id'].split("team")[-1],
            "time": float(datetime.strptime(obj['in_date'], fmt).timestamp() - datetime.strptime(contest['start_time'],
                                                                                                 fmt).timestamp()),
            "timestamp": datetime.strptime(obj['in_date'], fmt).timestamp(),
            "solved": solved,
            "penalty": penalty,
            "result": result
        }
        run.append(run_data)


# 示例数据结构
data = {
    "info": {
        "length": get_duration(contest['start_time'], contest['end_time']),
        "penalty": 20,
        "started": "False",
        "starttime": datetime.strptime(contest['start_time'], fmt).timestamp(),
        "title": contest['title'],
        "short-title": contest['title'],
        "scoreboard-freeze-length": format_duration_from_minutes(frozen_minute),
        "contest-id": 1
    },
    "region": region,
    "judgement": [
        {"id": 1, "acronym": "AC", "name": "Yes", "solved": "true", "penalty": "false"},
        {"id": 2, "acronym": "WA", "name": "No - Wrong Answer", "solved": "false", "penalty": "true"},
        {"id": 3, "acronym": "CE", "name": "No - Compile Error", "solved": "false", "penalty": "false"},
    ],
    "language": [
        {"id": 1, "name": "C"},
        {"id": 2, "name": "C++"},
        {"id": 3, "name": "Java"},
        {"id": 4, "name": "Python"}
    ],
    "problem": xml_problem,
    "team": team,
    "run": run,
    "finalized": {
        "last_gold": 1,
        "last_silver": 2,
        "last_bronze": 2,
        "time": 0
    }
}
if __name__ == '__main__':
    init_team_data(teams)
    init_problem(problem)
    init_solution(solution)
    # 生成并写入 xml 文件
    xml_output = generate_xml(data)
    with open("contest.xml", "w", encoding="utf-8") as f:
        f.write(xml_output)